/***************************************************************************
 *   Copyright (C) 2009 by pawel   *
 *   pawel@byszewski.pl   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef KROTKA_H
#define KROTKA_H
 

#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "command.h"
#include "helpers.h"
#include <fstream>
#include <iostream>


using namespace std;
/**
	@author pawel <pawel@byszewski.pl>
*/
class Tuple{
	public:
	vector<int> ints;
	vector<float> floats;
	vector<string> strings;
	char type[ELEMENTCOUNT];
		
public:
    Tuple(){
    	
    };
 	void wypisz(){
	  cout<<"\n***START KROTKA***"<<endl;
	  cout <<"\tinty: ";
	  	for(int i=0;i<ints.size();++i) cout <<ints.at(i)<<"*";
	  cout << endl;
	  cout <<"\tfloaty: ";
	  	for(int i=0;i<floats.size();++i) cout <<floats.at(i)<<"*";
	  cout << endl;
	  cout <<"\tstringi: ";
		for(int i=0;i<strings.size();++i) cout <<strings.at(i)<<"*";
	  cout << endl;
	  cout <<"***END KROTKA***\n"<<endl;
	}
// 	void wypiszToFile(std::ofstream stream){
//	  stream<<"\n***START KROTKA***"<<endl;
//	  stream <<"\tinty: ";
//	  	for(int i=0;i<ints.size();++i) stream <<ints.at(i)<<"*";
//	  stream << endl;
//	  stream <<"\tfloaty: ";
//	  	for(int i=0;i<floats.size();++i) stream <<floats.at(i)<<"*";
//	  stream << endl;
//	  stream <<"\tstringi: ";
//		for(int i=0;i<strings.size();++i) stream <<strings.at(i)<<"*";
//	  stream << endl;
//	  stream <<"***END KROTKA***\n"<<endl;
//	}
	char * createBuf(char *type, int size){
		char *buf=new char[size];
		int pos=0;
		for(int i=0; i<ELEMENTCOUNT;++i){
			//type[i]=c->type[i];
			if(type[i]==0){//int
				char *in=new char[4];
				int temp=ints.front();
				ints.erase(ints.begin());
				in=(char *)&temp;
				buf[pos++]=in[0];buf[pos++]=in[1];buf[pos++]=in[2];buf[pos++]=in[3];
				
			}
			else if(type[i]==1){//float
				char *in=new char[4];
				float temp=floats.front();
				floats.erase(floats.begin());
				in=(char *)&temp;
				buf[pos++]=in[0];buf[pos++]=in[1];buf[pos++]=in[2];buf[pos++]=in[3];
			}
			else if(type[i]==2){//string
				const char *buf1;
				buf1=strings.front().c_str();
				for( int i=0; i <= strings.front().length();++i){
					buf[pos++]=buf1[i];
					//if(*(buf1+i)==NULL) cout <<endl <<"NULL!"<<endl;
				}
				strings.erase(strings.begin());
			}
			else cout <<"cos nie bangla przy tworzeniu recordu z comendy -zly typ"<<endl;
			
		}
		return buf;
		
	}
	
	void createFromBuf(char *buf, char *type){
		int pos=0;
		//cout<<"KROTKA ";
		for(int i=0; i<ELEMENTCOUNT;++i){
			//type[i]=c->type[i];
			if(type[i]==0){//int
				int *k;
				char bufi[4];
				bufi[0]=buf[pos++];bufi[1]=buf[pos++];bufi[2]=buf[pos++];bufi[3]=buf[pos++];
				k=(int *)bufi;
				ints.push_back(*k);
		//		cout <<" int: "<<*k;
				
				
			}
			else if(type[i]==1){//float
				float *k;
				char bufi[4];
				bufi[0]=buf[pos++];bufi[1]=buf[pos++];bufi[2]=buf[pos++];bufi[3]=buf[pos++];
				k=(float *)bufi;
				floats.push_back(*k);
		//		cout <<" float: "<<*k;
			}
			else if(type[i]==2){//string
				string s(buf+pos);
				strings.push_back(s);
				pos+=(s.length()+1);
		//		cout <<" string: "<<s;
			}
			else cout <<"cos nie bangla przy tworzeniu recordu z comendy -zly typ"<<endl;
			
		}
		cout <<endl;
		 
	}
		
	int setFromCom(Command *c){
		string MODULE_NAME("setFromCom(CommandIn *c)");
		int size=0;
		for(int i =0; i<ELEMENTCOUNT;++i){
			type[i]=c->type[i];
			if(type[i]==0){//int
				int *k=(int*)c->list[i];
				//DEBUG(MODULE_NAME, *k);
				ints.push_back(*k);
				size+=4;
			}
			else if(type[i]==1){//float
				float *k=(float*)c->list[i];
				floats.push_back(*k);
				size+=4;
			}
			else if(type[i]==2){//string
				string *s=(string *)c->list[i];
				//DEBUG(MODULE_NAME, *s);
				strings.push_back(*s);
				size+=(s->length())+1;//bo pzy zamianie stringa na char dodaje sie nULL na końcu
			}
			else ;//cout <<"jakiś zjebany typ przy tworzeniu recordu z comendy"<<endl;
		};
		//DEBUG_ERR(MODULE_NAME, "Wyjscie z" + MODULE_NAME);
		return size;
		
	};
	
	int isSimilar(Tuple k, char * op){
		//cout<<"porównywanie krotek"<<endl;
		//wypisz();
		//k.wypisz();
		vector<int> ins=ints;
		vector<float> floas=floats;
		//cout<<"floas: "<<floas.size()<<"   floats: "<<floats.size()<<endl;
		vector<string> strins=strings;
		int sukces=1;
		for( int i=0;i<k.ints.size();++i)
			if(0==findInt(k.ints[i], &ins, (int)op[i])) return 0;
		for( int i=0;i<k.floats.size();++i)
			if(!findFloat(k.floats[i], &floas,(int) op[i])) return 0;
		for( int i=0;i<k.strings.size();++i)
			if(!findString(k.strings[i], &strins,(int) op[i])) return 0;
		
	}
	
	int findString(string f, vector<string> *ins, int op){
		for(int k=0;k<ins->size();++k){
        switch(op){
        case ROWNE:
			if((*ins)[k].compare(f)==0){
				ins->erase(ins->begin()+k);
				return 1;
			};break;
        case WIEKSZE:
			if((*ins)[k].compare(f)>0){
				ins->erase(ins->begin()+k);
				return 1;
			};break;
        case MNIEJSZE:
			if((*ins)[k].compare(f)<0){
				ins->erase(ins->begin()+k);
				return 1;
			};break;
		case MNIEJSZEROWNE:
				if((*ins)[k].compare(f)<=0){
					ins->erase(ins->begin()+k);
					return 1;
				};break;
		case WIEKSZEROWNE:
			if((*ins)[k].compare(f)>=1){
				ins->erase(ins->begin()+k);
				return 1;
			};break;
		case DOWOLNY:
			   return 1;

        };
		};
		//cout<<"nie znalazlem stringa"<<endl;
		return 0;
	}
	
	int findFloat(float f, vector<float> *ins, int op)
	{
		//cout <<"szukany w wectorze: "<<(*ins).size()<<endl;
		//cout <<"szukany float: "<<f<<"  porownywany *";
		for(int k=0;k<ins->size();++k)
		{
		//	cout <<floats[k]<<"*";
			switch(op)
			{
			case WIEKSZE:
				if(f>(*ins)[k]){
					ins->erase(ins->begin() + k);
					return 1;} break;
			case MNIEJSZE:
				if(f < (*ins)[k]){
					ins->erase(ins->begin() + k);
					return 1;} break;
			case DOWOLNY:
					//*ins->erase(*ins->begin()+k);
					return 1;
			 case ROWNE:
				if(f==(*ins)[k])
				{
					ins->erase(ins->begin()+k);
					return 1;
				}
				break;

			};

			};
		//cout <<endl<<"nie znalazlem floata"<<endl;
		return 0;
	}
	
	int findInt(int f, vector<int> *ins,  int op){
		for(int k=0;k<(*ins).size	();++k){
			switch(op){
			case WIEKSZE:
				if(f>(*ins)[k]){
					ins->erase(ins->begin()+k);
					return 1;}break;
			case MNIEJSZE:
				if(f<(*ins)[k]){
					ins->erase(ins->begin()+k);
					return 1;}break;
			case MNIEJSZEROWNE:
				if(f<=(*ins)[k]){
					ins->erase(ins->begin()+k);
					return 1;}break;
			case WIEKSZEROWNE:
				if(f<=(*ins)[k]){
					ins->erase(ins->begin()+k);
					return 1;}break;
			case ROWNE:
				if(f==(*ins)[k]){
					ins->erase(ins->begin()+k);
					return 1;}break;
			case DOWOLNY:
					return 1;

			};
		};
		//cout <<" nie znalazłem inta"<<endl;
		return 0;
	}
    ~Tuple(){};

};

#endif
